﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace MSI2
{
    public class Parser
    {
        private String file;
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="path">Path to to txt file with data.</param>
        public Parser(String path)
        {
            File = path;
        }
        
        public String File
        {
            get { return file; }
            set { file = value; }
        }
        /// <summary>
        /// Function to load data from selected file and parse them. Sequence of lettera from webmobis
        /// </summary>
        /// <returns>List of two arrays of type double. Sequence and Structure</returns>
        public List<ParsedData> LoadData()
        {
            String line;
            String data = "";
            List<ParsedData> output = new List<ParsedData>();
            ParsedData aminoacid;
            try
                {
                    // Create an instance of StreamReader to read from a file.
                    // The using statement also closes the StreamReader.
                    using (StreamReader sr = new StreamReader(File))
                    {
                        // Read and display lines from the file until the end of
                        // the file is reached.
                        while ((line = sr.ReadLine()) != null)
                        {
                            //line = sr.ReadLine();
                            if(line.StartsWith(">") && line.Contains("sequence")){
                                aminoacid = new ParsedData();
                                double[] sequence;
                                //Console.WriteLine("Nowy aminokwas: sekwencja: " + i);
                                data = "";
                                while ((line = sr.ReadLine()) != null && !line.Contains(">") && !line.Contains("secstr"))
                                {
                                    data += line;

                                }

                                aminoacid.SequenceString = data;

                                sequence = new double[21*data.Length];
                                Array.Clear(sequence,0,sequence.Length);
                                for (int j = 0; j < data.Length; j++)
                                {
                                    switch(data[j]){
                                        case 'A': 
                                            sequence[j*21] = 1;
                                            break;
                                        case 'N': 
                                            sequence[j*21+1] = 1;
                                            break;
                                        case 'R': 
                                            sequence[j*21+2] = 1;
                                            break;
                                        case 'C': 
                                            sequence[j*21+3] = 1;
                                            break;
                                        case 'F': 
                                            sequence[j*21+4] = 1;
                                            break;
                                        case 'G': 
                                            sequence[j*21+5] = 1;
                                            break;
                                        case 'Q': 
                                            sequence[j*21+6] = 1;
                                            break;
                                        case 'H': 
                                            sequence[j*21+7] = 1;
                                            break;
                                        case 'I': 
                                            sequence[j*21+8] = 1;
                                            break;
                                        case 'D': 
                                            sequence[j*21+9] = 1;
                                            break;
                                        case 'E': 
                                            sequence[j*21+10] = 1;
                                            break;
                                        case 'L': 
                                            sequence[j*21+11] = 1;
                                            break;
                                        case 'K': 
                                            sequence[j*21+12] = 1;
                                            break;
                                        case 'M': 
                                            sequence[j*21+13] = 1;
                                            break;
                                        case 'P': 
                                            sequence[j*21+14] = 1;
                                            break;
                                        case 'S': 
                                            sequence[j*21+15] = 1;
                                            break;
                                        case 'T': 
                                            sequence[j*21+16] = 1;
                                            break;
                                        case 'W': 
                                            sequence[j*21+17] = 1;
                                            break;
                                        case 'Y': 
                                            sequence[j*21+18] = 1;
                                            break;
                                        case 'V': 
                                            sequence[j*21+19] = 1;
                                            break;
                                        default: 
                                            sequence[j*21+20] = 0;
                                            break;
                                    }
                                }
                                aminoacid.Sequence = sequence;
                                //Console.WriteLine("Długość sekwencji: " + data.Length);
                                //Console.WriteLine(data);
                                if (line.Contains(">") && line.Contains("secstr"))
                                {
                                    double[] structure;
                                    //Console.WriteLine("Aminokwas: struktura: " + i);
                                    data = "";
                                    while ((line = sr.ReadLine()) != null && !line.Contains(">") && !line.Contains("sequence"))
                                    {
                                        data += line;
                                    }

                                    aminoacid.StructureString = data;

                                    aminoacid = Reclasify(aminoacid);

                                    structure = new double[3 * data.Length];
                                    Array.Clear(structure, 0, structure.Length);
                                    for (int j = 0; j < data.Length; j++)
                                    {
                                        switch (data[j])
                                        {
                                            case 'H':
                                            case 'G':
                                            case 'I':
                                                structure[j * 3] = 1;
                                                break;
                                            case 'E':
                                            case 'B':
                                                structure[j * 3 + 1] = 1;
                                                break;
                                            case 'T':
                                            case 'S':
                                            case ' ':
                                                structure[j * 3 + 2] = 1;
                                                break;
                                            default:
                                                structure[j * 3] = 0;
                                                structure[j * 3 + 1] = 0;
                                                structure[j * 3 + 2] = 0;
                                                break;
                                        }
                                    }
                                    aminoacid.Structure = structure;
                                    output.Add(aminoacid);
                                    /*
                                    Console.WriteLine("Długość struktury: " + data.Length);
                                    Console.WriteLine(data);
                                    Console.WriteLine("SPARSOWANE");
                                    Console.WriteLine("SEKWENCJA");
                                    foreach (double val in aminoacid.Sequence)
                                    {
                                        Console.Write(val);
                                    }
                                    Console.WriteLine("STRUKTURA");
                                    foreach (double val in aminoacid.Structure)
                                    {
                                        Console.Write(val);
                                    }
                                    */
                                }  
                            }
                        }
                    }
                    return output;
                }
                catch (Exception ex)
                {
                    // Let the user know what went wrong.
                    Console.WriteLine("The file could not be read.");
                    return null;
                }
        }

        private ParsedData Reclasify(ParsedData aminoacid)
        {
            aminoacid.StructureString = aminoacid.StructureString.Replace('G', 'H');
            aminoacid.StructureString = aminoacid.StructureString.Replace('I', 'H');
            aminoacid.StructureString = aminoacid.StructureString.Replace('B', 'E');
            aminoacid.StructureString = aminoacid.StructureString.Replace('T', 'L');
            aminoacid.StructureString = aminoacid.StructureString.Replace('S', 'L');
            aminoacid.StructureString = aminoacid.StructureString.Replace(' ', 'L');

            return aminoacid;
        }
    }
}
